﻿#region License

// Droid Manager - An Android Phone Tools Suite
// Copyright (C) 2011
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#endregion

using System;
using System.IO;

namespace DroidManager.Log
{
    /// <summary>
    /// Logger
    /// </summary>
    public sealed class Logger
    {
        /// <summary>
        /// Logger Streamwriter
        /// </summary>
        private StreamWriter _writer;

        /// <summary>
        /// Logger Instance
        /// </summary>
        private static Logger _instance;

        /// <summary>
        /// Initializes logger and creates new Streamwriter
        /// </summary>
        /// <param name="dirPath">Log dir path</param>
        internal Logger(string dirPath)
        {
            if (!IsFileOpenOrReadOnly(dirPath + @"\General.log"))
            {
                _writer = new StreamWriter(dirPath + @"\General.log");
            }
            else
            {
                _writer = new StreamWriter(string.Format(@"{0}\General.{1}.log", dirPath, DateTime.Now.Hour.ToString()
                                                                                          +
                                                                                          DateTime.Now.Minute.ToString() +
                                                                                          DateTime.Now.Second.ToString()));
            }
            _instance = this;
        }

        private bool IsFileOpenOrReadOnly(string file)
        {
            try
            {
                if ((File.GetAttributes(file) & FileAttributes.ReadOnly) != FileAttributes.ReadOnly)
                {
                    using (
                        FileStream stream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None)
                        )
                    {
                        try
                        {
                            stream.ReadByte();
                            return false;
                        }
                        catch (IOException)
                        {
                            return true;
                        }
                        finally
                        {
                            stream.Close();
                            stream.Dispose();
                        }
                    }
                }
                else
                    return true;
            }
            catch (FileNotFoundException)
            {
                return false;
            }
            catch (IOException)
            {
                return true;
            }
        }

        /// <summary>
        /// Returns Logger Instance
        /// </summary>
        public static Logger Instance
        {
            get { return _instance; }
        }

        /// <summary>
        /// Info Log
        /// </summary>
        /// <param name="message">Log message</param>
        public void Info(string message)
        {
            Console.WriteLine("[INFO][{0}] {1}", DateTime.Now, message);
            _writer.WriteLine("[INFO][{0}] {1}", DateTime.Now, message);
            _writer.Flush();
        }

        /// <summary>
        /// Warning Log
        /// </summary>
        /// <param name="message">Log message</param>
        public void Warning(string message)
        {
            Console.WriteLine("[WARN][{0}] {1}", DateTime.Now, message);
            _writer.WriteLine("[WARN][{0}] {1}", DateTime.Now, message);
            _writer.Flush();
        }

        /// <summary>
        /// Error Log
        /// </summary>
        /// <param name="message">Log message</param>
        public void Error(string message)
        {
            Console.WriteLine("[ERROR][{0}] {1}", DateTime.Now, message);
            _writer.WriteLine("[ERROR][{0}] {1}", DateTime.Now, message);
            _writer.Flush();
        }

        /// <summary>
        /// Debug Log
        /// </summary>
        /// <param name="message">Log message</param>
        public void Debug(string message)
        {
            Console.WriteLine("[DBG][{0}] {1}", DateTime.Now, message);
            _writer.WriteLine("[DBG][{0}] {1}", DateTime.Now, message);
            _writer.Flush();
        }
    }
}